package com.inspector.app.di.location;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.inspector.app.BuildConfig;
import com.inspector.app.ui.main.MainActivity;
import com.inspector.app.R;
import com.inspector.app.di.location.gnss.GnssStatusInstance;
import com.inspector.app.di.vo.event.EventLocation;
import com.inspector.app.di.vo.event.EventLocationChanged;
import com.inspector.app.util.ConstantUtil;
import com.inspector.app.util.LogUtil;
import com.mapsforge.org.oscim.location.LocationHandler;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * 新增高德和融合定位
 */
public class LocationService extends Service implements CustomLocationListener {

    public static final String TAG = LocationService.class.getSimpleName();
    public static final int notificationId = 100; //[不能为0]
    private final LocationHandler.LocalReceiver localReceiver = LocationHandler.localReceiver;
    private Notification notification;
    private LocationClient locationClient;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    public void onCreate() {
        super.onCreate();
        setup();
        LogUtil.e(TAG, "LocationService>>>>>onCreate 开始上传服务");
    }

    private void setup() {
        EventBus.getDefault().register(this);
        LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);

        //[启动前台服务通知]
        notification = initNotification();
        startForeground(notificationId, notification);

        //[监听卫星数]
        GnssStatusInstance.getInstance().registerGnssStatusCallback(locationManager);

        //[开启定位]
        /*ConfigJsonBean configBean = JsonUtil.getConfigJsonBean();
        ConstantUtil.COORDINATEINTERVALTIME = configBean.getCoordinateIntervalTime();
        ConstantUtil.COORDINATEINTERVALDIS = configBean.getCoordinateIntervalDis();*/
        // 2024/6/26 [暂不支持修改]
        ConstantUtil.COORDINATE_INTERVAL_TIME = 0;
        ConstantUtil.COORDINATE_INTERVAL_DIS = 0;
        locationClient = startLocation();

        //[地图引擎广播]
        localBroadcastManager = initLocationChangeBroadcast();
    }

    private Notification initNotification() {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        String CHANNEL_ID = BuildConfig.APPLICATION_ID;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, "导航通知",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(mChannel);
        }

        Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
//        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
        //[https://stackoverflow.com/questions/67045607/how-to-resolve-missing-pendingintent-mutability-flag-lint-warning-in-android-a]
        PendingIntent pendingIntent;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
        } else {
            pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        return new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.icon144)
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setContentTitle("导航定位")
                .setContentText("导航定位与诸元解算中......")
                .setContentIntent(pendingIntent)
                .setAutoCancel(false)
                .build();
    }

    private LocationClient startLocation() {
        stopLocation();

//        String locationTypeName = P.getPreferences(P.MapLocationEngine, CustomLocationType.LOCATION_DEFAULT.name());
        // TODO: 2024/7/3 [存储类]
        String locationTypeName = CustomLocationType.LOCATION_DEFAULT.name();
//        String locationTypeName = CustomLocationType.LOCATION_GD.name();
        CustomLocationType locationType = CustomLocationType.valueOf(locationTypeName);

        LocationClient locationClient = new LocationClient().newBuilder()
                .context(getApplicationContext())
                .addNotification(notification)
                .setLocationListener(this)
                .minInterval((long) (ConstantUtil.COORDINATE_INTERVAL_TIME * 1000))
                .minDistance((float) (ConstantUtil.COORDINATE_INTERVAL_DIS))
                .setLocationType(locationType)
                .build();

        locationClient.startLocation();
        return locationClient;
    }

    private void stopLocation() {
        if (locationClient == null) return;
        locationClient.stopLocation();
        locationClient = null;
    }

    public LocalBroadcastManager initLocationChangeBroadcast() {
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getApplicationContext());
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("LocationChangeBroadcast");
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
        return localBroadcastManager;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.e(TAG, "LocationService>>>>>onStartCommand intent:" + intent);
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() { //[不一定回调]
        super.onDestroy();
        try {
            //[取消卫星数监听]
            GnssStatusInstance.getInstance().unregisterGnssStatusCallback();
            if (locationClient != null) { //[取消定位]
                locationClient.stopLocation();
            }
            if (localBroadcastManager != null) { //[取消广播服务]
                localBroadcastManager.unregisterReceiver(localReceiver);
            }
            EventBus.getDefault().unregister(this);
            LogUtil.e(TAG, "LocationService>>>>>onDestroy 结束上传服务");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onLocationChanged(@Nullable Location location, boolean lastKnownLocation) {
        locationChanged(location, lastKnownLocation);
    }

    @Override
    public void onLocationChanged(@Nullable Location location) {
        locationChanged(location, false);
    }


    private void locationChanged(@Nullable Location location, boolean lastKnownLocation) {
        if (locationClient == null || location == null || localBroadcastManager == null) return;
        Location mLocation = LocationInstance.getInstance().onLocationChanged(locationClient, location, lastKnownLocation);
        if (mLocation == null) return;

        LocationInstance.getInstance().setLastKnownLocation(mLocation); //[接收到定位时刷新最后已知定位]
        sendBroadcast(localBroadcastManager, mLocation);
        EventBus.getDefault().post(new EventLocationChanged(mLocation));
    }

    public void sendBroadcast(LocalBroadcastManager localBroadcastManager, Location location) {
        Intent intent = new Intent("LocationChangeBroadcast");
        intent.putExtra("Longitude", location.getLongitude());
        intent.putExtra("Latitude", location.getLatitude());
        intent.putExtra("Speed", location.getSpeed());
        intent.putExtra("Bearing", location.getBearing());
        intent.putExtra("Accuracy", location.getAccuracy());
        localBroadcastManager.sendBroadcast(intent);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        LogUtil.e(TAG, "onStatusChanged provider:" + provider + " status:" + status);
    }

    @Override
    public void onProviderEnabled(String provider) {
        LogUtil.e(TAG, "定位可用 provider:" + provider);
        LocationInstance.getInstance().setProviderEnabled(true);
    }

    @Override
    public void onProviderDisabled(String provider) {
        LogUtil.e(TAG, "定位不可用 provider:" + provider);
        LocationInstance.getInstance().setProviderEnabled(false);
    }

    //[配置页面-定位时间间隔设置]
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void eventServiceLocation(@NonNull EventLocation eventLocation) {
        locationClient = startLocation();
    }



}
